package components.plugins.effects {
	import UIFree.uif_app;
	
	import UIUtils.uif_color;
	import UIUtils.uif_util;
	
	import flash.display.BitmapData;
	import flash.display.BitmapDataChannel;
	import flash.display.BlendMode;
	import flash.filters.BitmapFilter;
	import flash.filters.BlurFilter;
	import flash.filters.GlowFilter;
	import flash.geom.ColorTransform;
	import flash.geom.Matrix;
	import flash.geom.Point;
	import flash.geom.Rectangle;

	public class clte_countur extends clt_baseEffect {
		private var _filter: BitmapFilter;
		public function clte_countur(a_params:Object) {
			super(uif_util.unionObj({
				blur		: 20,
				noise		: 0,
				color		: 0xFFFFFF,
				alpha		: 1,
				steps		: 0,
				stepScale	: 1.05,
				stepCenter	: [0.5, 0.5],
				stepRotate	: 0,
				fading		: 0,
				inner		: false,
				stepTranslate	: [0, 0]
			}, a_params));
			updateFilter();
		}
		
		override public function execute(bitmapData: BitmapData):void {
			var app		: clt_clothingBase = uif_app.instance() as clt_clothingBase;
			app.getResult(bitmapData.width, bitmapData.height, function(figure	: BitmapData): void {
				var coutur: BitmapData = new BitmapData(bitmapData.width, bitmapData.height, true, 0xFFFFFF);
				
				coutur.draw(figure, null, new ColorTransform(0, 0, 0));
				coutur.applyFilter(coutur, coutur.rect, new Point(), _filter);
				
				if (params.noise) {
					var noiseLevel: uint = 0x88 * params.noise;
					var noise: BitmapData = new BitmapData(bitmapData.width, bitmapData.height, true, 0xFFFFFF);
					noise.noise(10, 0, 0xFF, BitmapDataChannel.ALPHA, true);
					coutur.merge(noise, coutur.rect, new Point(), 0, 0, 0, noiseLevel);
					coutur.threshold(coutur, coutur.rect, new Point(), '<', noiseLevel << 24, 0x00000000, 0xFF000000);
				}
				
				if (params.steps) {
					var blur: BlurFilter = new BlurFilter(4, 4, 2);
					var cp		: BitmapData = new BitmapData(bitmapData.width, bitmapData.height, true, 0xFFFFFF);
					var mat		: Matrix = new Matrix();
					var center	: Point = new Point(cp.width * params.stepCenter[0], cp.height * params.stepCenter[1]);
					var ct		: ColorTransform; 
					var k		: Number = 1/params.steps;
					if (doubleColors) {
						var a1		: Array = uif_color.uintToRGBA(params.color[0]);
						var a2		: Array = uif_color.uintToRGBA(params.color[1]);
						var csteps	: Array = new Array();
						for (var n: int=0; n<a1.length; n++) {
							csteps[n] = (a2[n] - a1[n]) * k;
						}
						ct = new ColorTransform(1, 1, 1, 1, Math.round(csteps[1]), Math.round(csteps[2]), Math.round(csteps[3]), Math.round(csteps[0]));
					} else ct = new ColorTransform(1, 1, 1, 1 - params.fading);
					
					mat.translate(-center.x, -center.y);
					mat.scale(params.stepScale, params.stepScale);
					mat.translate(params.stepTranslate[0], params.stepTranslate[1]);
					mat.rotate(params.stepRotate);
					mat.translate(center.x, center.y);
					var b_tmp: BitmapData = new BitmapData(bitmapData.width, bitmapData.height, true, 0xFFFFFF);
					
					for (var i: int=0; i<params.steps; i++) {
						cp.draw(coutur);
						cp.applyFilter(cp, cp.rect, new Point(), blur);
						b_tmp.draw(cp);
						cp.draw(b_tmp, mat, ct);
					}
					b_tmp.dispose();
					//	coutur.draw(cp, null, new ColorTransform(1, 1, 1, 1));
					bitmapData.draw(cp);
					//bitmapData.draw(coutur);
					//bitmapData.draw(figure);
				} else bitmapData.draw(coutur);
			}, {
				noback		: true,
				resultOnly	: true
			});
		}
		
		protected function updateFilter(): void {
			_filter = new GlowFilter(doubleColors?params.color[0]:params.color, params.alpha, params.blur, params.blur, 2, 2, params.inner, true);
		}
		
		protected function get doubleColors(): Boolean {
			return params.color is Array;
		}
		
		override public function incValue1():void {
			params.blur = changeValue(params.blur, 2, 100);
			updateFilter();
		}
		
		override public function incValue2():void {
			params.alpha = changeValue(params.alpha, 0.1, 1);
			updateFilter();
		}
		
		override public function incValue3():void {
			params.noise = changeValue(params.noise, 0.1, 1);
		}
		
		override protected function getParamName():Array {
			return [
				locale.BLUR,
				locale.ALPHA,
				locale.NOISE,
				locale.BLENDMODE
			];
		}
		
		override protected function getValues():Array {
			return [
				params.blur,
				params.alpha * 100,
				params.noise * 100,
				blendMode100
			];
		}
		
		override protected function setValues(a_set:Array):void {
			params.blur  = a_set[0];
			params.alpha = a_set[1] * .01;
			params.noise = a_set[2] * .01;
			updateFilter();
			super.setValues(a_set);
		}		
	}
}